/*
 * This file is part of algowala.
 *
 * algowala is copyright (c) 2012 Jagannathan Sampath <algowala@jagernot.com>
 *
 * algowala is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * algowala is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with algowala.  If not, see <http://www.gnu.org/licenses/>.
 *
*/

#ifndef __stock
#define __stock

#include <string>
#include <list>

#include "random.h"
#include "color.h"

#include <iostream>
using namespace std;

struct tick_data_t { // for a stock
  double price; // current price
  int volume; // current volume
  double timestamp; // current time
  tick_data_t (double _price, int _volume, double _timestamp) : price (_price), volume (_volume), timestamp (_timestamp) {}
};

template <typename T> struct stock_param { // stock parameter; eg., price, volume (see below)
  
  T value; // current value
  T volatility; // value moves up or down by volatility at the most
  rnd<T> dice; // returns random number between -volatility and +volatility
  
  stock_param (T _value = 0, T _volatility = 0) {
    value = _value;
    set_volatility (_volatility);
  }
  
  stock_param& operator= (const stock_param& sp) {
    if (this != &sp) {
      value = sp.value;
      set_volatility (sp.volatility);
    }
    return *this;
  }
  
  stock_param (const stock_param& sp) {
    operator= (sp);
  }
  
  void move () { // randomly move the value of parameter
    value += dice ();
    if (value <= 0) value = 0;
  }
  
  void set_volatility (T v) {
    volatility = v;
    dice = rnd<T> (-v, v);
  }
  
};

struct stock {
  
  std::string symbol; // eg., RBS 
  std::string company; // eg., Royal_Bank_of_Scotland_PLC
  
  stock_param<double> price; // current price
  stock_param<int> volume; // current volume
    
  // price/volume changes n times in m seconds
  int n_times;
  int m_secs;
  
  double update_time; // price/volume changes every update seconds; calculated from n_times & m_secs
  double last_change_time; // time of last price/volume change
  
  std::list<tick_data_t> tick_data; // list of all price/volume movements ie ticks for this stock
  int num_ticks; // total number of ticks
  
  // visualisation
  //
  
  // to display only visible ticks on the viewer
  std::list<tick_data_t>::iterator start, end;
  int startn, endn;
  
  color clr; // color
    
  stock (const std::string& sym = "", const std::string& com = "", double _price = 0, double _volatility = 0, int _volume = 0, int _vol_volatility = 0, int _n_times = 0, int _m_secs = 0, double now = 0);
  stock (const stock& s);
  stock& operator= (const stock& s);
  
  int tick (double time_now); // move price/volume of stock
  
  void calc_update_time () {
    update_time = m_secs * 1. / n_times;
  }
  
};

stock* get_stock_ptr (const std::string& symbol);

#endif
